package com.me.mygdxgame;

import java.io.IOException;
import java.util.ArrayList;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.math.Vector2;
import com.badlogic.gdx.utils.Array;
import com.badlogic.gdx.utils.XmlReader;
import com.badlogic.gdx.utils.XmlReader.Element;
import com.me.mygdxgame.Components.BoundingBox;
import com.me.mygdxgame.Components.Transform;
import com.me.mygdxgame.GameObjects.Tile;
import com.me.mygdxgame.GameObjects.Unit;

public class Map{
	private static Map instance = null;
	private static Tile[][] mapArray;
	private static int mapSizeX = 4;
	private static int mapSizeY = 4;
	static int placementcounter = 0;
	private static int tileSize;
	
	private Map(){
		
	}
	public static Map getInstance(){
		if(instance == null){
			instance = new Map();
		}
		return instance;
	}
	
	public static int getTileSize() { 
		return tileSize;
	}

	/*	<summary>
	 * Author Jan-Hendrik Kahle
	 * Create Map from XML...
	 * 	</summary>
	 */
	public static Tile[][] createMapFromXML() throws IOException {
		
		XmlReader reader = new XmlReader();
		
		Element root = reader.parse(Gdx.files.local("data/Map.xml"));
		Array<Element> tiles = 	root.getChildrenByName("Tile");
		
		int mapSizeX = root.getChildByName("mapSize").getIntAttribute("x");
		int mapSizeY = root.getChildByName("mapSize").getIntAttribute("y");
		tileSize = root.getChildByName("mapSize").getIntAttribute("tileSize");
		
		Tile finalArr[][] = new Tile[mapSizeX][mapSizeY];
		
		fillMapArray(tiles, finalArr);
		
		setAdjacentTiles(mapSizeX, mapSizeY, finalArr);		
		
		return finalArr;
	}
	
	/* <summary>
	 * Author Jan-Hendrik Kahle
	 * Create Map : Create Tilemap from the list of Elements from the XML 
	 * </summary>
	 */
	private static void fillMapArray(Array<Element> tiles,
			Tile[][] finalArr) {
		TileFactory factory = new TileFactory();
		for (Element tile : tiles) {
			boolean obst = tile.getBooleanAttribute("obstacle");
			int posiX = tile.getIntAttribute("x");
			int posiY = tile.getIntAttribute("y");
			Vector2 posi = new Vector2(0.0f + (float)posiX * (float)tileSize, 0.0f + (float)posiY * (float)tileSize);
			Tile tempTile = (Tile) factory.create(posi);
			tempTile.setObstacle(obst);
			finalArr[posiX][posiY] = tempTile;
			
		}
	}

	/* <summary>
	 * Author Jan-Hendrik Kahle
	 * Create Map : Set the adjacent Tile-Pointers for the respective Tiles 
	 * </summary>
	 */
	private static void setAdjacentTiles(int mapSizeX, int mapSizeY,
			Tile[][] finalArr) {
		for (int x = 0; x <= (mapSizeX-1); x++)
		{
			for(int y = 0; y <= (mapSizeY-1); y++)
			{
				Tile baseTile = finalArr[x][y];
				if(!((x+1)>=mapSizeX))  {
					Tile rightTile = finalArr[x+1][y];
					baseTile.setNeighborTile(DIRECTION.RIGHT, rightTile);
					rightTile.setNeighborTile(DIRECTION.LEFT, baseTile);
				}
				if (!((y+1)>=mapSizeY)) {
					Tile bottomTile = finalArr[x][y+1];
					baseTile.setNeighborTile(DIRECTION.DOWN, bottomTile);					
					bottomTile.setNeighborTile(DIRECTION.UP, baseTile);
				}																
				baseTile.setName(("TileX " + x + " TileY: " + y));
				
			}
		}
		
	}
/*	public void getAttackArea(Unit attackingUnit){
		UNITTYPE attackingUnitsType = attackingUnit.getUnittype();
		Tile tileOccupiedByAttackingUnit = attackingUnit.getOccupiedTile();
		if(attackingUnitsType == UNITTYPE.FLAMETHROWER){
			
		}
		else if(attackingUnitsType == UNITTYPE.SHOTGUN){
			
		}
		else if(attackingUnitsType == UNITTYPE.SNIPER){
			
		}
		else if(attackingUnitsType == UNITTYPE.SOLDIER){
			
		}
	}
	
	void getFlamethowersAttackArea(Tile startTile){
		ArrayList<Tile> area = new ArrayList<Tile>();
		
	}
	*/
	
	static ArrayList<Tile> getSelectionArea(){
		mapArray = TabletWars.map;
		final int selectionAreaSize = 2;
		ArrayList<Tile> tempArrayList = new ArrayList<Tile>();
		for(int x = 0; x <= mapSizeX; x++){
			for(int y = 0; y < selectionAreaSize; y++){
				if(RoundHandler.getInstance().playerOnesTurn){
					tempArrayList.add(mapArray[x][y]);
				}
				else{
					tempArrayList.add(mapArray[x][mapSizeY-y]);
				}
			}
		}
		return tempArrayList;
	}
	static AbstractFactory getCurrentFactory(){
		if(placementcounter < 2){
			System.out.println("soldier " + RoundHandler.getInstance().playerOnesTurn);
			return new SoldierFactory();
		}
		else if(placementcounter < 4){
			System.out.println("shotgun " + RoundHandler.getInstance().playerOnesTurn);
			return new ShotgunFactory();
		}
		else if(placementcounter < 6){
			System.out.println("sniper " + RoundHandler.getInstance().playerOnesTurn);
			return new SniperFactory();
		}
		else if(placementcounter <= 8){
			System.out.println("flamethrower " + RoundHandler.getInstance().playerOnesTurn);
			return new FlameFactory();
		}
		System.out.println(placementcounter);
		return null;
	}
	
	static void switchGamestateAfterPlacement(){
		if(placementcounter >= 8){
			RoundHandler.getInstance().gamestate = GAMESTATE.SELECTION;
		}
	}
	
	public static void placement(){
		ArrayList<Tile> selectionArea = getSelectionArea();
		switchGamestateAfterPlacement();
		for(Tile currentTile:selectionArea){
			BoundingBox currentBoundingBox = (BoundingBox)currentTile.getComponent("BoundingBox");
			Transform currentTransform = (Transform)currentTile.getComponent("Transform");
			currentBoundingBox.touchFunction(Gdx.input.getX(), Gdx.input.getY());
			
			if(Gdx.input.justTouched()) {
				if(currentBoundingBox.touched() && !currentTile.isObstacle()){
					Unit tempUnit = (Unit) getCurrentFactory().create(new Vector2(currentTransform.getPosition().x,currentTransform.getPosition().y));
					tempUnit.setOccupiedTile(currentTile);
					currentTile.setOccupyUnit(tempUnit);
					TabletWars.units.add(tempUnit);
					if(RoundHandler.getInstance().playerOnesTurn){		
						TabletWars.player1Units.add(tempUnit);
						RoundHandler.getInstance().switchPlayer();
						placementcounter++;
						break;
					}
					else{
						TabletWars.player2Units.add(tempUnit);
						RoundHandler.getInstance().switchPlayer();
						placementcounter++;
						break;
					}					
				}
			}
		}
	}
}
